﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Reflection;
using prohomework.Models.SqlBase;
namespace prohomework.Models.SqlClient
{

        public abstract class SqlBaseDBHandler<T> : BaseDBHandler<T>
        {
            private SqlBaseExecutant executant;

            public SqlBaseDBHandler(string connectionString)
            {
                this.executant = new SqlBaseExecutant(connectionString);
            }

            public void CloseReader(SqlDataReader reader)
            {
                reader.Close();
                this.executant.CloseConnection();
            }
            /// <summary>
            /// 添加整数型存储过程参数，当参数为 Int32.MinValue 时添加空参数
            /// </summary>
            /// <param name="paramname"></param>
            /// <param name="value"></param>
            public void AddNullableIntParameter(string paramname, int value)
            {
                if (value == Int32.MinValue)
                {
                    this.Parameters.AddWithValue(paramname, System.DBNull.Value);
                }
                else
                {
                    this.Parameters.AddWithValue(paramname, value);
                }
            }

            /// <summary>
            /// 添加十进制数存储过程参数，当参数为 Decimal.MinValue 时添加空参数
            /// </summary>
            /// <param name="paramname"></param>
            /// <param name="value"></param>
            public void AddNullableDecimalParameter(string paramname, decimal value)
            {
                if (value == decimal.MinValue)
                {
                    Parameters.AddWithValue(paramname, System.DBNull.Value);
                }
                else
                {
                    Parameters.AddWithValue(paramname, value);
                }
            }

            public void AddNullableDoubleParameter(string paramname, double value)
            {
                if (value == double.MinValue)
                {
                    Parameters.AddWithValue(paramname, System.DBNull.Value);
                }
                else
                {
                    Parameters.AddWithValue(paramname, value);
                }
            }

            /// <summary>
            /// 添加日期时间型存储过程参数，当参数为 DateTime.MinValue 空时添加空参数
            /// </summary>
            /// <param name="paramname"></param>
            /// <param name="value"></param>
            public void AddNullableDateParameter(string paramname, DateTime value)
            {
                if (value == DateTime.MinValue)
                {
                    this.Parameters.AddWithValue(paramname, System.DBNull.Value);
                }
                else
                {
                    this.Parameters.AddWithValue(paramname, value);
                }
            }
            /// <summary>
            /// 添加存储过程参数，当参数为空时添加空参数
            /// </summary>
            /// <param name="paramname"></param>
            /// <param name="value"></param>
            public void AddNullableParameters(string paramname, object value)
            {
                if (value == null)
                    this.Parameters.AddWithValue(paramname, System.DBNull.Value);
                else
                {
                    this.Parameters.AddWithValue(paramname, value);
                }
            }

            /// <summary>
            /// 添加字符型存储过程参数，当字符串为空或长度为零字符串时添加空参数
            /// </summary>
            /// <param name="paramname"></param>
            /// <param name="value"></param>
            public void AddNullableStringParameter(string paramname, string value)
            {
                if (value == null || value == "")
                    this.Parameters.AddWithValue(paramname, System.DBNull.Value);
                else
                    this.Parameters.AddWithValue(paramname, value);
            }

            /// <summary>
            /// 将字段值转换为整数，当字段值为空时为Int32.MinValue
            /// </summary>
            /// <param name="obj"></param>
            /// <returns></returns>
            public static int ParseInt(object obj)
            {
                return ParseInt(obj, Int32.MinValue);
            }
            /// <summary>
            /// 将字段值转换为二进制数组
            /// </summary>
            /// <param name="obj"></param>
            /// <returns></returns>
            public static byte[] ParseImage(object obj)
            {
                if (obj == null)
                {
                    return null;
                }
                try
                {
                    return (byte[])obj;
                }
                catch
                {
                    return null;
                }
            }

            /// <summary>
            /// 转换为空的字符串，当字段值为空时返回空值
            /// </summary>
            /// <param name="obj"></param>
            /// <returns></returns>
            public static string ParseString(object obj)
            {
                if (obj == null)
                    return null;
                try
                {
                    string str = (string)obj;
                    return str;
                }
                catch
                {
                    return null;
                }
            }
            /// <summary>
            /// 将字段值转换为字符串，当字段值为空时转换为指定值
            /// </summary>
            /// <param name="obj"></param>
            /// <param name="s">为空字段时的指定值</param>
            /// <returns></returns>
            public static string ParseString(object obj, string s)
            {
                if (obj == null)
                    return s;
                try
                {
                    string str = (string)obj;
                    return str;
                }
                catch
                {
                    return null;
                }
            }
            /// <summary>
            /// 将字段值转换为逻辑值，当字段为空值时转换为指定值
            /// </summary>
            /// <param name="obj"></param>
            /// <param name="def">当字段为空值时转换为指定值</param>
            /// <returns></returns>
            public static bool ParseBool(object obj, bool def)
            {
                if (obj == null)
                    return def;
                try
                {
                    bool b = (bool)obj;
                    return b;
                }
                catch
                {
                    return def;
                }
            }
            /// <summary>
            /// 将字段值转换为逻辑值，当字段为空值时转换为：false
            /// </summary>
            /// <param name="obj"></param>
            /// <returns></returns>
            public static bool ParseBool(object obj)
            {
                return ParseBool(obj, false);
            }
            /// <summary>
            /// 将字段值转换为整型，当字段为空值时转换为指定值
            /// </summary>
            /// <param name="obj"></param>
            /// <param name="def">当字段为空值时转换为指定值</param>
            /// <returns></returns>
            public static int ParseInt(object obj, int def)
            {
                if (obj == null)
                    return def;
                int num;
                try
                {
                    num = (int)obj;
                    return num;
                }
                catch
                {
                    return def;
                }
            }
            /// <summary>
            /// 将字段值转换为时间日期，当字段为空值时为指定时间值
            /// </summary>
            /// <param name="obj"></param>
            /// <param name="def">当字段为空值时为指定时间值</param>
            /// <returns></returns>
            public static DateTime ParseDateTime(object obj, DateTime def)
            {
                if (obj == null)
                    return def;
                DateTime time;
                try
                {
                    time = (DateTime)obj;
                    return time;
                }
                catch
                {
                    return def;
                }
            }
            /// <summary>
            /// 将字段值转换为时间日期，当字段为空值时为DateTime.MinValue
            /// </summary>
            /// <param name="obj"></param>
            /// <returns></returns>
            public static DateTime ParseDateTime(object obj)
            {
                if (obj == null)
                    return DateTime.MinValue;
                DateTime time;
                try
                {
                    time = (DateTime)obj;
                    return time;
                }
                catch
                {
                    return DateTime.MinValue;
                }
            }

            public static double ParseDouble(object obj)
            {
                if (obj == null)
                    return double.MinValue;
                double d;
                try
                {
                    d = (double)obj;
                    return d;
                }
                catch
                {
                    return double.MinValue;
                }
            }

            public static double ParseDouble(object obj, double def)
            {
                if (obj == null)
                    return def;
                double d;
                try
                {
                    d = (double)obj;
                    return d;
                }
                catch
                {
                    return def;
                }
            }

            /// <summary>
            /// 将字段值转换为十进制数，当字段值为空时取值为 decimal.MinValue
            /// </summary>
            /// <param name="obj"></param>
            /// <returns></returns>
            public static decimal ParseDecimal(object obj)
            {
                if (obj == null)
                    return decimal.MinValue;
                decimal d;
                try
                {
                    d = (decimal)obj;
                    return d;
                }
                catch
                {
                    return decimal.MinValue;
                }
            }
            /// <summary>
            /// 将字段值转换为十进制数，当字段值为空时取值为指定值
            /// </summary>
            /// <param name="obj"></param>
            /// <param name="def">当字段值为空时取值为指定值</param>
            /// <returns></returns>
            public static decimal ParseDecimal(object obj, decimal def)
            {
                if (obj == null)
                    return def;
                decimal d;
                try
                {
                    d = (decimal)obj;
                    return d;
                }
                catch
                {
                    return def;
                }
            }


            public CommandType CmdType
            {
                set { this.executant.CommandType = value; }
            }
            public SqlBaseExecutant Executant
            {
                get { return executant; }
            }
            public string CommandText
            {
                get { return this.executant.CommandText; }
                set { this.executant.CommandText = value; }
            }

            public SqlParameterCollection Parameters
            {
                get { return this.executant.Parameters; }
            }

            protected virtual void AddParametersFromModel(T model)
            {
                Type type = model.GetType();
                PropertyInfo[] properties = type.GetProperties();
                foreach (PropertyInfo property in properties)
                {
                    this.Parameters.AddWithValue("@" + property.Name,
                            type.InvokeMember(property.Name,
                        BindingFlags.Public | BindingFlags.NonPublic |
                BindingFlags.Instance | BindingFlags.GetProperty,
                        null, model, null));
                }
            }
            protected abstract T AssembleFromReader(SqlDataReader reader);
            protected abstract T GetModel(int id);
        }
    
}